SPB Git

Repository Public

route.ts 2.1 KB 62 lines typescript

1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// /api/admin/submissions/[id]/reply — réponse au demandeur depuis le panel.3// Le message est D'ABORD écrit en base (source de vérité), puis envoyé par4// courriel (Resend) ; l'échec d'envoi est signalé mais le message reste.5// Pose first_response_at (délai de première réponse du dashboard).6import { NextRequest, NextResponse } from "next/server";7import {8  findSubmissionById,9  insertMessage,10  logEvent,11  touchFirstResponse,12} from "@/lib/comms/db";13import { getAdminSession, canViewSubmission } from "@/lib/comms/admin-auth";14import { sendAdminReply } from "@/lib/comms/receipt-email";1516export async function POST(17  req: NextRequest,18  { params }: { params: Promise<{ id: string }> },19) {20  const session = await getAdminSession();21  if (!session)22    return NextResponse.json({ error: "Non autorisé." }, { status: 401 });23  const id = Number((await params).id);24  const sub = Number.isInteger(id) ? findSubmissionById(id) : undefined;25  if (!sub || !canViewSubmission(session, sub))26    return NextResponse.json({ error: "Demande introuvable." }, { status: 404 });2728  const body = (await req.json().catch(() => null)) as { body?: string } | null;29  const text = (body?.body ?? "").trim().slice(0, 12000);30  if (!text)31    return NextResponse.json({ error: "Message vide." }, { status: 422 });32  if (!sub.email)33    return NextResponse.json(34      { error: "Cette demande n'a pas de courriel (soumission anonyme) — utilisez une note interne." },35      { status: 422 },36    );3738  insertMessage({39    submission_id: sub.id,40    sender_type: "admin",41    sender_admin_id: session.id,42    body: text,43    channel: "email",44  });45  touchFirstResponse(sub.id);46  logEvent(sub.id, session.id, "reponse", "Réponse envoyée au demandeur");4748  let sent = true;49  try {50    await sendAdminReply({51      to: sub.email,52      name: [sub.first_name, sub.last_name].filter(Boolean).join(" ") || "bonjour",53      reference: sub.reference,54      body: text,55    });56  } catch (e) {57    sent = false;58    console.error("[admin/reply] Resend :", (e as Error).message);59  }60  return NextResponse.json({ ok: true, sent });61}62
Files main
Menu

Theme